package com.aicode.core.tools.security;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * 功能：支付宝MD5加密处理核心文件，不需要修改 版本：3.1 修改日期：2010-11-01 说明：
 * 以下代码只是为了方便商家测试而提供的样例代码，商家可以根据自己网站的需要，按照技术文档编写,并非一定要使用该代码。 该代码仅供学习和研究支付宝接口使用，只是提供一个
 */
public class Md5 {
  /** Used building output as Hex */
  private static final char[] DIGITS = {
    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
  };

  private static final String hexDigits[] = {
    "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"
  };

  /**
   * 对字符串进行MD5加密
   *
   * @param text 明文
   * @return 密文
   */
  public static String md5(String text) {
    MessageDigest msgDigest = null;

    try {
      msgDigest = MessageDigest.getInstance("MD5");
    } catch (NoSuchAlgorithmException e) {
      throw new IllegalStateException("System doesn't support MD5 algorithm.");
    }

    try {
      msgDigest.update(text.getBytes("UTF-8")); // 注意改接口是按照指定编码形式签名

    } catch (UnsupportedEncodingException e) {

      throw new IllegalStateException("System doesn't support your  EncodingException.");
    }

    byte[] bytes = msgDigest.digest();

    String md5Str = new String(encodeHex(bytes));

    return md5Str;
  }

  public static String md5(String origin, String charsetname) {
    String resultString = null;
    try {
      resultString = new String(origin);
      MessageDigest md = MessageDigest.getInstance("MD5");
      if (charsetname == null || "".equals(charsetname)) {
        resultString = byteArrayToHexString(md.digest(resultString.getBytes()));
      } else {
        resultString = byteArrayToHexString(md.digest(resultString.getBytes(charsetname)));
      }
    } catch (Exception exception) {
    }
    return resultString;
  }

  private static String byteArrayToHexString(byte b[]) {
    StringBuffer resultSb = new StringBuffer();
    for (int i = 0; i < b.length; i++) {
      resultSb.append(byteToHexString(b[i]));
    }

    return resultSb.toString();
  }

  private static String byteToHexString(byte b) {
    int n = b;
    if (n < 0) {
      n += 256;
    }
    int d1 = n / 16;
    int d2 = n % 16;
    return hexDigits[d1] + hexDigits[d2];
  }

  public static char[] encodeHex(byte[] data) {

    int l = data.length;

    char[] out = new char[l << 1];

    // two characters form the hex value.
    for (int i = 0, j = 0; i < l; i++) {
      out[j++] = DIGITS[(0xF0 & data[i]) >>> 4];
      out[j++] = DIGITS[0x0F & data[i]];
    }

    return out;
  }
}
